package com.bank.gui;

import com.bank.utils.CommunicationWrapper;
import com.bank.utils.CustomScrollBarUI;
import com.bank.utils.Operation;
import com.bank.utils.TextFieldLimiter;
import com.bank.utils.Toast;
import java.awt.print.PrinterException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.AbstractDocument;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Moofie
 */
public class PassbookPanel extends javax.swing.JPanel {

    private CommunicationWrapper cw;
    private String branchCode;
    private int portNo;

    /**
     * Creates new form PassbookPanel
     */
    public PassbookPanel(CommunicationWrapper cw, String branchCode, int portNo) {
        this.cw = cw;
        this.branchCode = branchCode;
        this.portNo = portNo;
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        txtAccNo = new javax.swing.JTextField();
        btnCheck = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        jtaPassbookInfo = new javax.swing.JTextArea();
        btnReset = new javax.swing.JButton();
        btnPrint = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();
        jSeparator1 = new javax.swing.JSeparator();

        setLayout(null);

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jLabel1.setText("Account No.");
        add(jLabel1);
        jLabel1.setBounds(20, 35, 90, 30);

        AbstractDocument aDocAcc = (AbstractDocument)txtAccNo.getDocument();
        aDocAcc.setDocumentFilter(new TextFieldLimiter("\\d{0,14}"));
        txtAccNo.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        add(txtAccNo);
        txtAccNo.setBounds(110, 35, 200, 30);

        btnCheck.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        btnCheck.setText("Check");
        btnCheck.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCheckActionPerformed(evt);
            }
        });
        add(btnCheck);
        btnCheck.setBounds(310, 35, 110, 30);

        jScrollPane1.getVerticalScrollBar().setUI(new CustomScrollBarUI());

        jtaPassbookInfo.setEditable(false);
        jtaPassbookInfo.setColumns(20);
        jtaPassbookInfo.setFont(new java.awt.Font("Monospaced", 0, 12)); // NOI18N
        jtaPassbookInfo.setRows(5);
        jtaPassbookInfo.setEnabled(false);
        jScrollPane1.setViewportView(jtaPassbookInfo);

        add(jScrollPane1);
        jScrollPane1.setBounds(20, 70, 400, 260);

        btnReset.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        btnReset.setText("Reset");
        btnReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnResetActionPerformed(evt);
            }
        });
        add(btnReset);
        btnReset.setBounds(20, 340, 160, 30);

        btnPrint.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        btnPrint.setText("Print");
        btnPrint.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPrintActionPerformed(evt);
            }
        });
        add(btnPrint);
        btnPrint.setBounds(260, 340, 160, 30);

        jLabel5.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
        jLabel5.setText("TRANSACTION HISTORY");
        add(jLabel5);
        jLabel5.setBounds(20, 5, 400, 20);
        add(jSeparator1);
        jSeparator1.setBounds(10, 25, 420, 5);
    }// </editor-fold>//GEN-END:initComponents

    private void btnPrintActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPrintActionPerformed
        try {
            // trying to print the text area's content
            jtaPassbookInfo.print();
        } catch (PrinterException ex) {
            Logger.getLogger(PassbookPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_btnPrintActionPerformed

    private void btnCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCheckActionPerformed
        if (txtAccNo.getText().isEmpty()) {
            // account number field left empty, prompt error message
            Toast.makeText(getParent(), "Please enter account number.", Toast.LENGTH_SHORT).display();
        } else {
            // account number is not empty, proceed to construct data
            jtaPassbookInfo.setEnabled(true); // enable the text area
            try {
                JSONObject j = new JSONObject();
                // specific operation
                j.put("operation", Operation.TRANSACTION);
                JSONObject content = new JSONObject();
                // put in necessary data
                content.put("accno", txtAccNo.getText());
                content.put("port", this.portNo);
                content.put("bCode", this.branchCode);
                content.put("address", InetAddress.getLocalHost().getHostAddress());
                j.put("content", content);
                // after constructed data, send to server
                cw.send(j, InetAddress.getLocalHost(), 5000);
                // wait for server's reply
                JSONObject result = cw.receive();
                generateTransactionLog(result);
            } catch (JSONException | UnknownHostException ex) {
                ex.printStackTrace();
            }
        }
    }//GEN-LAST:event_btnCheckActionPerformed

    private void btnResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnResetActionPerformed
        // TODO add your handling code here:
        clear();
    }//GEN-LAST:event_btnResetActionPerformed

    /**
     * construct the transaction logs with the given data and 
     * display in text area
     * 
     * @param json JSON string that store transaction logs
     */
    private void generateTransactionLog(JSONObject json) {
        try {
            if (json.getBoolean("record")) {
                JSONArray jsArr = json.getJSONObject("content").getJSONArray("result");
                jtaPassbookInfo.setText("#   Transaction Date    Transaction Type      Amount\n");
                jtaPassbookInfo.append("========================================================\n");
                for (int i = 0; i < jsArr.length(); i++) {
                    JSONObject temp = jsArr.getJSONObject(i);
                    String line =
                            String.format("%-6d%-22s%-16sRM%9.2f", i + 1, temp.getString("transactionDate"),
                            (temp.getString("transactionType").equals("CRD") ? "Credit" : "Debit"),
                            temp.getDouble("amount"));
                    jtaPassbookInfo.append(line + "\n");
                }
            } else {
                jtaPassbookInfo.setText("No record found, did you enter the correct account number?");
            }
        } catch (JSONException ex) {
            ex.printStackTrace();
        }
    }

    public void clear() {
        txtAccNo.setText("");
        jtaPassbookInfo.setText("");
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnCheck;
    private javax.swing.JButton btnPrint;
    private javax.swing.JButton btnReset;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JTextArea jtaPassbookInfo;
    private javax.swing.JTextField txtAccNo;
    // End of variables declaration//GEN-END:variables
}
